﻿using LView.CMS.Core.Extensions;
using LView.CMS.Core.Options;
using LView.CMS.IServices;
using LView.CMS.Models;
using LView.CMS.ViewModels;
using Microsoft.Extensions.Options;
using SQLBuilder.Core.Repositories;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using LView.CMS.Core;
using System.Net.Http.Headers;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Hosting;

namespace LView.CMS.Services
{
    public class AssetsService : IAssetsService
    {
        private readonly List<AssetsOptions> _assetsOptions;
        private readonly IRepository _repository;
        private readonly IHostingEnvironment _hostEnv;

        public AssetsService(IOptions<List<AssetsOptions>> options, Func<string, IRepository> handler, IHostingEnvironment hostEnv)
        {
            _repository = handler(null);
            _assetsOptions = options.Value;
            _hostEnv = hostEnv;
        }

        public async Task<(BaseResult, LFile)> AddAssetsAsync(CourseAddOrModify input)
        {
            var result = new BaseResult();
            var fileEntity = new LFile();
            //提取上传的文件后缀
            var suffix = Path.GetExtension(input.FileName)?.ToLower();
            var options = _assetsOptions.FirstOrDefault(x => x.FileTypes.Contains(suffix));
            if (options == null)
            {
                result.ResultCode = ResultCodeAddMsgKeys.CommonExceptionCode;
                result.ResultMsg = $"{ResultCodeAddMsgKeys.CommonExceptionMsg} : Unkonow Filetype When Call Add , InputAssetsType : {input.AssetsType}";
                return (result, null);
            }

            //封面数据
            var imageOption = _assetsOptions.FirstOrDefault(x => x.AssetsType == "Image");
            if (imageOption == null && input.CoverImage == null)
            {
                result.ResultCode = ResultCodeAddMsgKeys.CommonExceptionCode;
                result.ResultMsg = $"{ResultCodeAddMsgKeys.CommonExceptionMsg} : Can't Find AssetsType of Image";
                return (result, null);
            }

            if (input.FileData == null || input.FileData.Length <= 0)
            {
                result.ResultCode = ResultCodeAddMsgKeys.CommonExceptionCode;
                result.ResultMsg = $"{ResultCodeAddMsgKeys.CommonExceptionMsg} : FileData Can't Be Null";
                return (result, null);
            }

            try
            {
                ////允许的文件格式
                //var fileTypes = options.FileTypes.Split(',').Select(x => x.ToLower());
                ////判断文件后缀名是否合法
                //if (!string.IsNullOrEmpty(suffix) && fileTypes.Contains(suffix))
                //    throw new Exception("");

                //var path = Path.Combine(options.FilePath, input.Directory);
                var path = Path.Combine(options.FilePath, options.AssetsType);  //配置的路径+资源文件类型路径+任务名  作为文件夹  input.TaskName
                if (!Directory.Exists(path))
                    Directory.CreateDirectory(path);

                var name = $"{input.FileIndex}_{input.FileName}.lms";
                var partFile = Path.Combine(path, name);
                var fullFile = Path.Combine(path, input.FileName);

                //保存文件，如果已经是最后一个分片，组合
                if (await SaveFile(input.FileData.OpenReadStream(), partFile) && input.FileIndex == input.FileTotal)
                {
                    using (var fs = new FileStream(fullFile, FileMode.Create))
                    {
                        for (var i = 1; i <= input.FileTotal; i++)
                        {
                            var combFile = Path.Combine(path, $"{i}_{input.FileName}.lms");
                            var bytes = await File.ReadAllBytesAsync(combFile);
                            fs.Write(bytes, 0, bytes.Length);
                            File.Delete(combFile);
                        }
                        //保存图片
                        if (input.CoverImage != null && input.CoverImage.Length > 0)
                        {
                            var coverImagePath = Path.Combine(imageOption.FilePath, "CoverImage");
                            if (!Directory.Exists(coverImagePath))
                                Directory.CreateDirectory(coverImagePath);

                            var coverImageName = $"{Guid.NewGuid()}.{input.CoverImage.FileName.Substring(".")}";
                            var coverImageFullName = Path.Combine(coverImagePath, coverImageName);
                            using (var stream = new FileStream(coverImageFullName, FileMode.Create))
                            {
                                await input.CoverImage.CopyToAsync(stream);
                                //entity.CoverImage = coverImageName;
                            }
                        }
                        //TODO 解析pdf/ppt
                        if (options.AssetsType == "Other")
                        {
                            //将pdf/ppt解析成图片，并存取至特定路径下
                        }

                        fileEntity.Id = Guid.NewGuid().ToString();
                        fileEntity.Name = input.FileName;
                        fileEntity.Type = options.AssetsType;
                        fileEntity.Path = fullFile;
                        await MongodbHelper.Instance.InsertOneAsync<LFile>(fileEntity);
                    }
                }
                result.ResultCode = ResultCodeAddMsgKeys.CommonObjectSuccessCode;
                if (input.FileIndex == input.FileTotal - 1)
                    result.ResultMsg = ResultCodeAddMsgKeys.CommonObjectSuccessMsg + "Current File Process OK";
                else
                    result.ResultMsg = ResultCodeAddMsgKeys.CommonObjectSuccessMsg + "All File Merge OK";
            }
            catch (Exception ex)
            {
                result.ResultCode = ResultCodeAddMsgKeys.CommonExceptionCode;
                result.ResultMsg = ResultCodeAddMsgKeys.CommonExceptionMsg + $":{ex.Message}";
                return (result, null);
            }

            return (result, fileEntity);
        }

        public (int, string, string) UploadImage(IFormFile imgFile)
        {
            if (imgFile != null && !imgFile.FileName.IsNullOrEmpty())
            {
                long size = 0;
                string tempname = "";
                var filename = ContentDispositionHeaderValue
                                .Parse(imgFile.ContentDisposition)
                                .FileName
                                .Trim('"');
                var extname = filename.Substring(filename.LastIndexOf("."), filename.Length - filename.LastIndexOf("."));
                #region 判断后缀
                //if (!extname.ToLower().Contains("jpg") && !extname.ToLower().Contains("png") && !extname.ToLower().Contains("gif"))
                //{
                //    return Json(new { code = 1, msg = "只允许上传jpg,png,gif格式的图片.", });
                //}
                #endregion
                #region 判断大小
                long mb = imgFile.Length / 1024 / 1024; // MB
                if (mb > 1)
                {
                    return (1, "只允许上传小于 1MB 的图片.", "");
                }
                #endregion
                var filename1 = DateTime.Now.ToString("yyyyMMddHHmmssfff") + new Random().Next(1000, 9999) + extname;
                tempname = filename1;
                var path = _hostEnv.WebRootPath;
                string dir = DateTime.Now.ToString("yyyyMMdd");
                if (!Directory.Exists(_hostEnv.WebRootPath + $@"\upload\{dir}"))
                {
                    Directory.CreateDirectory(_hostEnv.WebRootPath + $@"\upload\{dir}");
                }
                filename = _hostEnv.WebRootPath + $@"\upload\{dir}\{filename1}";
                size += imgFile.Length;
                using (FileStream fs = System.IO.File.Create(filename))
                {
                    imgFile.CopyTo(fs);
                    fs.Flush();
                }
                return (0, "上传成功 ", $"/upload/{dir}/{filename1}");
            }
            else
                return (1, "无有效图片文件", "");
        }

        private async Task<bool> SaveFile(Stream fileStream, string filePath)
        {
            using (var fs = File.Create(filePath))
            {
                var buffer = new byte[2048];
                var count = 0;
                while ((count = await fileStream.ReadAsync(buffer, 0, buffer.Length)) != 0)
                {
                    await fs.WriteAsync(buffer, 0, count);
                }
                return true;
            }
        }
    }
}
